﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using iTeachSoft.CoreObjects;
using iTeachSoft.Presentation.Code.Managers;
using iTeachSoft.Code.Managers;
using iTeachSoft.Presentation.Code.Wrappers;
using System.Windows.Controls.Primitives;
using System.Diagnostics;
using iTeachSoft.Presentation.Code.Utility;
using System.IO;

namespace iTeachSoft.Presentation.Controls
{
    /// <summary>
    /// Interaction logic for SlideViewControl.xaml
    /// </summary>
    public partial class SlideViewControl : UserControl
    {
        private Slide mCurrentSlide = null;

        public Slide CurrentSlide
        {
            get { return mCurrentSlide; }
            set
            {
                mCurrentSlide = value;
                ReflectSlide();
            }
        }

        public SlideViewControl()
        {
            InitializeComponent();
            AddEventsHandlers();
        }

        private void AddEventsHandlers()
        {
            this.MouseUp += new MouseButtonEventHandler(SlideViewControl_MouseUp);
            this.SizeChanged += new SizeChangedEventHandler(SlideViewControl_SizeChanged);

            this.miSlideProperties.Click += new RoutedEventHandler(miSlideProperties_Click);
            this.miProperties.Click += new RoutedEventHandler(miProperties_Click);

            this.miSlideNextSlide.Click += new RoutedEventHandler(miSlideNextSlide_Click);
            this.miSlidePreviousSlide.Click += new RoutedEventHandler(miSlidePreviousSlide_Click);

            this.imageSlideView.MouseDown += new MouseButtonEventHandler(imageSlideView_MouseDown);

            EventsManagement.Instance.SelectedSlideIndexChanged += new EventHandler<iTeachSoft.Presentation.Code.Utility.SingleItemEventArgs<int>>(Instance_SelectedSlideIndexChanged);
            EventsManagement.Instance.ReflectSlideViewerRequested += new EventHandler(Instance_ReflectSlideViewerRequested);
        }

        void imageSlideView_MouseDown(object sender, MouseButtonEventArgs e)
        {
            RuntimeStorage.CurrentSelectedShape = null;
        }

        private void ReflectSlide()
        {
            BitmapImage image = new BitmapImage();
            image.BeginInit();

            image.UriSource = new Uri(CurrentSlide.BackgroundPath);
            System.Drawing.Size imageSize = CurrentSlide.Size;
            if (CurrentSlide.Size.Width == 0 && CurrentSlide.Size.Height == 0)
                imageSize = CurrentSlide.ParentProject.SlidesSize;

            image.DecodePixelWidth = imageSize.Width;
            if (CurrentSlide.PreserveRation)
                image.DecodePixelHeight = imageSize.Height;

            image.EndInit();

            imageSlideView.Source = image;
            imageSlideView.Width = image.Width;
            imageSlideView.Height = image.Height;

            canvasContainer.Children.Clear();
            foreach (BaseSlideObject slideObject in CurrentSlide.SlideObjects)
                InsertSlideObject(slideObject);

            EventsManagement.Instance.OnReflectTreeViewRequested(this, EventArgs.Empty);

            gridLayout.UpdateLayout();
            canvasContainer.UpdateLayout();

            RenderCanvas();
        }

        private void RenderCanvas()
        {
            RenderTargetBitmap renderImage = new RenderTargetBitmap(CurrentSlide.Size.Width, CurrentSlide.Size.Height, 96, 96, PixelFormats.Pbgra32);
            renderImage.Render(gridLayout);

            Size size = new Size(CurrentSlide.Size.Width, CurrentSlide.Size.Height);
            gridLayout.Measure(size); 

            string file = FileManager.GetSlidePreviewPath(CurrentSlide);
            BitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(renderImage));

            using (Stream stm = File.Create(file))
            {
                encoder.Save(stm);
            }
        }

        private void InsertSlideObject(BaseSlideObject slideObject)
        {
            if (slideObject.GetType() == typeof(Annotation))
            {
                var annotationShape = new AnnotationShape(slideObject as Annotation);
                this.canvasContainer.Children.Add(annotationShape);
            }

            if (slideObject.GetType() == typeof(RectangleWithText))
            {
                var textAnnotation = new TextAnnotationShpae(slideObject as RectangleWithText);
                this.canvasContainer.Children.Add(textAnnotation);
            }
            //TODO other objects
        }

        void miProperties_Click(object sender, RoutedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        void miSlideProperties_Click(object sender, RoutedEventArgs e)
        {
            ActionsManager.ShowSlideProperties(CurrentSlide);
        }

        void SlideViewControl_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (RuntimeStorage.ToBeInsertedObject != null)
            {
                var slideObject = RuntimeStorage.ToBeInsertedObject;
                RuntimeStorage.ToBeInsertedObject = null;
                slideObject.Bounds = new System.Drawing.Rectangle(new System.Drawing.Point((int)e.GetPosition(this).X, (int)e.GetPosition(this).Y), slideObject.Bounds.Size);

                CurrentSlide.SlideObjects.Add(slideObject);
                ReflectSlide();

                EventsManagement.Instance.OnReflectProjectInvoked(this, EventArgs.Empty);
            }
        }

        void SlideViewControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            RuntimeStorage.SlideViewControlBounds = GraphicsUtility.GetBounds(this, Application.Current.MainWindow);
        }

        void Instance_SelectedSlideIndexChanged(object sender, iTeachSoft.Presentation.Code.Utility.SingleItemEventArgs<int> e)
        {
            //reflect the new slide
            if (RuntimeStorage.CurrentProject.Slides.Count > e.Item && RuntimeStorage.CurrentProject.Slides.Count > 0)
                CurrentSlide = RuntimeStorage.CurrentProject.Slides[e.Item];
        }

        void Instance_ReflectSlideViewerRequested(object sender, EventArgs e)
        {
            ReflectSlide();
        }

        void miSlidePreviousSlide_Click(object sender, RoutedEventArgs e)
        {
            int index = RuntimeStorage.CurrentProject.Slides.IndexOf(CurrentSlide);
            if (index - 1 >= 0)
                EventsManagement.Instance.OnSelectedSlideIndexChanged(this, new SingleItemEventArgs<int>(index - 1));
        }

        void miSlideNextSlide_Click(object sender, RoutedEventArgs e)
        {
            int index = RuntimeStorage.CurrentProject.Slides.IndexOf(CurrentSlide);
            if (index + 1 < RuntimeStorage.CurrentProject.Slides.Count)
                EventsManagement.Instance.OnSelectedSlideIndexChanged(this, new SingleItemEventArgs<int>(index + 1));
        }
    }
}
